package org.jupiter.blog.service.service.impl;

import org.jupiter.blog.api.convertor.JupiterRolePermissionStructConvertor;
import org.jupiter.blog.api.domain.JupiterRolePermission;
import org.jupiter.blog.api.dto.JupiterRolePermissionDTO;
import org.jupiter.blog.common.utils.UuidUtils;
import org.jupiter.blog.service.mapper.JupiterRolePermissionMapper;
import org.jupiter.blog.service.service.JupiterRolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class JupiterRolePermissionServiceImpl implements JupiterRolePermissionService {

	@Autowired
	private JupiterRolePermissionMapper rolePermissionMapper;

	@Autowired
	private JupiterRolePermissionStructConvertor rolePermissionStructConvertor;

	@Override
	public JupiterRolePermissionDTO getById(String uuid) {
		JupiterRolePermission rolePermission = rolePermissionMapper.selectByUuid(uuid);
		return rolePermissionStructConvertor.toDto(rolePermission);
	}

	@Override
	public List<JupiterRolePermissionDTO> getAll() {
		List<JupiterRolePermission> rolePermissions = rolePermissionMapper.selectAll();
		return rolePermissions.stream()
				.map(rolePermissionStructConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	public List<String> getByRoleId(String roleId) {
		List<JupiterRolePermission> rolePermissions = rolePermissionMapper.selectByRoleUuid(roleId);
		return rolePermissions.stream()
				.map(JupiterRolePermission::getPermissionUuid)
				.collect(Collectors.toList());
	}

	@Override
	public List<JupiterRolePermissionDTO> getByPermissionId(String permissionId) {
		List<JupiterRolePermission> rolePermissions = rolePermissionMapper.selectByPermissionId(permissionId);
		return rolePermissions.stream()
				.map(rolePermissionStructConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional
	public void create(JupiterRolePermissionDTO dto) {
		JupiterRolePermission rolePermission = rolePermissionStructConvertor.toEntity(dto);
		if (!StringUtils.hasText(rolePermission.getUuid())){
			rolePermission.setUuid(UUID.randomUUID().toString());
		}
		rolePermission.setCreateTime(LocalDateTime.now());
		rolePermission.setUpdateTime(LocalDateTime.now());
		rolePermissionMapper.insert(rolePermission);
	}

	@Override
	@Transactional
	public void update(JupiterRolePermissionDTO dto) {
		JupiterRolePermission rolePermission = rolePermissionStructConvertor.toEntity(dto);
		rolePermission.setUpdateTime(LocalDateTime.now());
		rolePermissionMapper.updateByUuidSelective(rolePermission);
	}

	@Override
	@Transactional
	public void delete(String uuid) {
		rolePermissionMapper.deleteByUuid(uuid);
	}

	@Override
	@Transactional
	public void deleteByRoleId(String roleId) {
		rolePermissionMapper.deleteByRoleUuid(roleId);
	}

	@Override
	@Transactional
	public void deleteByPermissionId(String permissionId) {
		rolePermissionMapper.deleteByPermissionId(permissionId);
	}

	@Override
	@Transactional
	public void assignPermissionsToRole(JupiterRolePermissionDTO rolePermissionDto) {
		// 先删除角色的所有权限
		rolePermissionMapper.deleteByRoleUuid(rolePermissionDto.getRoleUuid());
		if (CollectionUtils.isEmpty(rolePermissionDto.getPermissionUuids())){
			return; // 没有新的权限，直接返回
		}
		List<JupiterRolePermission> batchData = rolePermissionDto.getPermissionUuids().stream()
				.map(permissionId -> {
					JupiterRolePermission rolePermission = new JupiterRolePermission();
					rolePermission.setUuid(UuidUtils.randomUuidWithoutDash());
					rolePermission.setRoleUuid(rolePermissionDto.getRoleUuid());
					rolePermission.setPermissionUuid(permissionId);
					rolePermission.setCreateTime(LocalDateTime.now());
					rolePermission.setUpdateTime(LocalDateTime.now());
					return rolePermission;
				})
				.toList();

		rolePermissionMapper.insertBatch(batchData);
	}

	@Override
	@Transactional
	public void assignRolesToPermission(String permissionId, List<String> roleIds) {
		// 先删除权限的所有角色
		rolePermissionMapper.deleteByPermissionId(permissionId);

		// 重新分配角色
		for (String roleId : roleIds){
			JupiterRolePermission rolePermission = new JupiterRolePermission();
			rolePermission.setUuid(UUID.randomUUID().toString());
			rolePermission.setRoleUuid(roleId);
			rolePermission.setPermissionUuid(permissionId);
			rolePermission.setCreateTime(LocalDateTime.now());
			rolePermission.setUpdateTime(LocalDateTime.now());
			rolePermissionMapper.insert(rolePermission);
		}
	}
}
